﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Linq;
  


namespace UI
{

    public partial class MapTabPage : System.Windows.Forms.TabPage , MapWinGIS.ICallback
    {
        IColorScheme color_scheme;
       
        ProgressBar p;

        Dictionary<int, MapSpecifics> SortedMapSpecifics = new Dictionary<int, MapSpecifics>();
        
        public MapTabPage(System.Windows.Forms.TabControl tab1, List<string> FileNames, string Label)
        {
            Location = tab1.Location;
            Size = tab1.Size;

           

            InitializeComponent();

            this.Text = Label;

           
            AddLayers(FileNames);
             

        }
        public void Progress(string KeyOfSender, int Percent, string Message)
        {
            p.Update(Percent);
        }
        int Year(string FileName)
        {
            int year = -1; ;
            if (int.TryParse(System.Text.RegularExpressions.Regex.Match(FileName, @"\d+").Value, out year))
            {
                return year;
            }
            return year;
        }
        private IColorScheme GetColorScheme(int BinWidth)
        {
            if (BinWidth == 1) return new ColorScheme();
            else return new ClassifiedColorScheme(new byte[] { 0, 255 }, new byte[] { 0, 255 }, new byte[] { 255, 255 }, 10);
        }
        private int GetBinWidth(int MapMin, int MapMax)
        {
            int Range = MapMax - MapMin;
            if (Range > 10) return (int)(Range / 10);
            else return 1;
        }
        private MapWinGIS.GridColorScheme GetGridScheme(int MapMin, int MapMax, int BinWidth)
        {
            MapWinGIS.GridColorScheme gridScheme = new MapWinGIS.GridColorScheme();

            float i = MapMin;
            while (i <= MapMax)
            {
                MapWinGIS.GridColorBreak g = new MapWinGIS.GridColorBreak();

                g.LowValue = i - 0.01;
                g.HighValue = i + BinWidth - 0.01;

                System.Drawing.Color mycolor = color_scheme.NextColor;

                g.HighColor = g.LowColor = mycolor.ToUInt();

                string Label = g.LowValue.ToString() + "-" + g.HighValue.ToString();

                TreeNode node = new TreeNode(Label);
                node.BackColor = mycolor;
                node.NodeFont = new Font(Legend.Font, FontStyle.Regular);

                Legend.Nodes.Add(node);

                gridScheme.InsertBreak(g);

                i += BinWidth;
            }

            return gridScheme;
        }
            
        private void AddLayers(List<string> FileNames)
        {
            int MapMin = int.MaxValue;
            int MapMax = int.MinValue;
            
            foreach (string FileName in FileNames)
            {
                string ext = System.IO.Path.GetExtension(FileName);

                if (ext == ".bgd" || ext == ".asc" || ext == ".img")
                {
                    p = new ProgressBar(System.IO.Path.GetFileName(FileName));
                    p.Show();
                    p.Refresh();

                    string MapLabel = System.IO.Path.GetFileNameWithoutExtension(FileName);

                    int year = Year(FileName);

                    MapWinGIS.Grid grid = new MapWinGIS.GridClass();

                    grid.Open(FileName, MapWinGIS.GridDataType.UnknownDataType, true, MapWinGIS.GridFileType.UseExtension, this);

                    MapMin = Math.Min(MapMin, (int)float.Parse(grid.Minimum.ToString()));
                    MapMax = Math.Max(MapMax, (int)float.Parse(grid.Maximum.ToString()));

                    SortedMapSpecifics.Add(year, new MapSpecifics(year, MapLabel, grid));
                     
                }
            }

            int BinWidth = GetBinWidth(MapMin, MapMax);

            color_scheme = GetColorScheme(BinWidth);

            MapWinGIS.GridColorScheme gridScheme = GetGridScheme(MapMin, MapMax, BinWidth);
            

            foreach (KeyValuePair<int, MapSpecifics> MapSpecs in SortedMapSpecifics)
            {
                //convert the grid to a image
                MapSpecs.Value.Image = new MapWinGIS.UtilsClass().GridToImage(MapSpecs.Value.grid, gridScheme, this);
                MapSpecs.Value.Image.CustomColorScheme = gridScheme;

                MapSpecs.Value.LayerHandle = axMap1.AddLayer(MapSpecs.Value.Image, true);

                //set the layer name
                axMap1.set_LayerName(MapSpecs.Value.LayerHandle, MapSpecs.Value.MapLabel);

                axMap1.SetImageLayerColorScheme(MapSpecs.Value.LayerHandle, gridScheme);

                axMap1.Refresh();

                //close the grid
                MapSpecs.Value.grid.Close();
                p.Close();
            }

        }
        /*
        private void AddLayer(string FileName)
        {
            string ext = System.IO.Path.GetExtension(FileName);

            if (ext == ".bgd" || ext == ".asc" || ext == ".img")
            {
                string MapLabel = System.IO.Path.GetFileNameWithoutExtension(FileName);
                treeView1.Nodes.Add(new TreeNode (MapLabel));
                treeView1.Nodes[treeView1.Nodes.Count-1].NodeFont = new Font(treeView1.Font, FontStyle.Regular);

                MapLabels.Add(MapLabel, treeView1.Nodes.Count - 1);
                
                p = new ProgressBar(System.IO.Path.GetFileName(FileName));
                p.Show();
                p.Refresh();

                MapWinGIS.Grid grid = new MapWinGIS.GridClass();

               
                grid.Open(FileName, MapWinGIS.GridDataType.UnknownDataType, true, MapWinGIS.GridFileType.UseExtension, this);

                int MapMin = (int) float.Parse(grid.Minimum.ToString());
                int MapMax = (int)float.Parse(grid.Maximum.ToString());
                int Range = MapMax - MapMin;

                int BinWidth = 1;
                if (Range > 10 )
                {
                    BinWidth = (int)(Range / 10);
                    color_scheme = new ClassifiedColorScheme(new byte[] { 0, 255 }, new byte[] { 0, 255 }, new byte[] { 255, 255 }, 10);
                }
                else color_scheme = new ColorScheme2();


                float i = MapMin;
 
                while (i <= MapMax)
                {
                    AddBreak(MapLabel , i - 0.01, i + BinWidth - 0.01, color_scheme.NextColor);

                    i += BinWidth;
                }

                //convert the grid to a image
                MapWinGIS.Image image = new MapWinGIS.UtilsClass().GridToImage(grid, gridScheme, this);
 
                int handle = axMap1.AddLayer(image, true);

                LayerNamesAndHandles.Add(MapLabel, handle);

                image.CustomColorScheme = gridScheme;
                
                //set the layer name
                axMap1.set_LayerName(handle, System.IO.Path.GetFileNameWithoutExtension(grid.Filename));

                axMap1.SetImageLayerColorScheme(handle, gridScheme);

                axMap1.Refresh();
                
                //close the grid
                grid.Close();
                p.Close();
            }
            
             
        }
        */
        private Rectangle NodeBounds(TreeNode node)
        {
            // Set the return value to the normal node bounds.
           
            Rectangle bounds = node.Bounds;
            if (node.Tag != null)
            {
                // Retrieve a Graphics object from the TreeView handle 
                // and use it to calculate the display width of the tag.
                System.Drawing.Graphics g = this.Legend.CreateGraphics();

                Font tagFont = new Font("Helvetica", 8, FontStyle.Bold);
                int tagWidth = (int)g.MeasureString(node.Tag.ToString(), tagFont).Width + 6;
                
                // Adjust the node bounds using the calculated value.
                bounds.Offset(tagWidth / 2, 0);
                bounds = Rectangle.Inflate(bounds, tagWidth / 2, 0);
                g.Dispose();
            }

            return bounds;

        }
         
        public void Error(string KeyOfSender, string ErrorMsg)
        {
            // TODO:  Add Form1.Error implementation
        }
        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            TreeNode clickedNode = this.Legend.GetNodeAt(e.X, e.Y);
            if (clickedNode != null)
            {
                if (NodeBounds(clickedNode).Contains(e.X, e.Y))
                {
                    Legend.SelectedNode = clickedNode;
                }

            }
        }

        private void treeView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            int LayerHandle =  new List<MapSpecifics>(SortedMapSpecifics.Values.ToList().Where(x => x.MapLabel == Layers.SelectedNode.Text))[0].LayerHandle;
            axMap1.set_LayerVisible(LayerHandle, !axMap1.get_LayerVisible(LayerHandle));
            axMap1.Invalidate();
            axMap1.Refresh();
        }

        public void SetLayersInvisible()
        {
            foreach (int LayerHandle in SortedMapSpecifics.Values.Select(l => l.LayerHandle).ToList())
            {
                axMap1.set_LayerVisible(LayerHandle, false);
                axMap1.Invalidate();
                axMap1.Refresh();
            }
        }
       
        public void ZoomToMaxExtents()
        {
            axMap1.ZoomToMaxExtents();
        }
        public void Pan()
        {
            axMap1.CursorMode = MapWinGIS.tkCursorMode.cmPan;
        }
        public void ZoomOut()
        {
            axMap1.CursorMode = MapWinGIS.tkCursorMode.cmZoomOut;
        }
        public void ZoomIn()
        { 
             axMap1.CursorMode = MapWinGIS.tkCursorMode.cmZoomIn;
        }
        public void PlayAnimation()
        {
            SetLayersInvisible();

            string textbase = Legend.Nodes[0].Text;
            foreach (MapSpecifics map in SortedMapSpecifics.Values)
            {
                axMap1.set_LayerVisible(map.LayerHandle,  true);

                Legend.Nodes[0].Text = textbase + map.Year;
                Legend.Nodes[0].NodeFont = new Font(Legend.Font, FontStyle.Bold);

                Legend.Update();
                Legend.Invalidate();
                Legend.Refresh();
                axMap1.Invalidate();
                axMap1.Refresh();
                System.Threading.Thread.Sleep(5000);
            }
            Legend.Nodes[0].Text = textbase;
            Legend.Nodes[0].NodeFont = new Font(Legend.Font, FontStyle.Regular);
        }

        

        
        

        

        
    }
}
